package com.qzsoft.zhjd.common.utils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;

import java.beans.PropertyDescriptor;

public class BeanValidator {
    /**
     * 验证某个bean
     *
     * @param object 被校验的参数
     * @return 如果对象正常校验通过，返回null
     */
    public static <T> String validBean(T object) {
        // 获得验证器
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

        if (null == object) {
            return "对象不可为空";
        }

        Set<ConstraintViolation<Object>> constraints = validator.validate(object);
        if (CollectionUtils.isEmpty(constraints)) {
            return null;
        }

        StringBuilder builder = new StringBuilder();
        constraints.forEach(c -> builder.append(c.getPropertyPath()).append(c.getMessage()).append(";"));
        return builder.toString();
    }

    /**
     * 验证List
     *
     * @param lists 被校验的list
     * @return 如果对象正常校验通过，返回null,如果为空则返回对象不可为空，如果字段校验失败，返回具体信息
     */
    public static <T> String validList(List<T> lists) {

        if (CollectionUtils.isEmpty(lists)) {
            return "对象不可为空";
        }

        return validBean(lists.get(0));
    }

    /**
     * 两个bean之间相互传值
     *
     * @param from
     * @param to
     * @return
     */
    public static Object convertBean2Bean(Object from, Object to) {
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(to.getClass());
            PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();
            Class<?> classType = from.getClass();
            for (PropertyDescriptor p : ps) {
                Method getMethod = p.getReadMethod();
                Method setMethod = p.getWriteMethod();
                if (getMethod != null && setMethod != null) {
                    try {
                        Method fromGetMethod = classType.getMethod(getMethod.getName());
                        Object result = fromGetMethod.invoke(from);
                        setMethod.invoke(to, result);
                    } catch (Exception e) {
//						log.error("convertBean2Bean-->发生异常，异常原因：{}", e.getMessage(), e);
                    }
                }
            }

        } catch (Exception e) {
//            log.error("convertBean2Bean-->发生异常，异常原因：{}",e.getMessage(), e);
        }
        return to;
    }

    public static <T> T  map2Bean(Map<String,Object> map,Class<T> t)throws Exception{
        if (map == null) {
            return null;
        } else {
            String json = JSONObject.toJSONString(map);
            System.out.println("json"+json);
            // 使用clazz对应类的默认构造器创建实例
            T t1 = JSONObject.parseObject(json, t);
            Assert.notNull(t1,"转换失败！");
            return t1;
        }

    }


    /**
     将"1,2,3,4,5..."这种形式的字符串转成"'1','2','3','4'..."这种形式

     @param strs
     @return
     */
    public static String converString(String strs) {
        if (StringUtils.isNotBlank(strs)) {
            String[] idStrs = strs.trim().split(",");
            if (null != idStrs && idStrs.length > 0) {
                StringBuffer sbf = new StringBuffer("");
                for (String str : idStrs) {
                    if (StringUtils.isNotBlank(str)) {
                        sbf.append("'").append(str.trim()).append("'").append(",");
                    }
                }
                if (sbf.length() > 0) {
                    sbf = sbf.deleteCharAt(sbf.length() - 1);
                    return sbf.toString();
                }
            }
        }
        return "";
    }

    @SuppressWarnings("all") //消除警告
    private static Class<?> populate(Map<String, String> map, Class<?> t) throws Exception {

        //拿到 user 的对应的class对象
        Class<?> clazz = (Class<?>) t.getClass();

        //通过反射拿到所有的属性

        //拿到所有的属性值
        Field[] fields = clazz.getDeclaredFields();

        //遍历属性

        for (int i = 0; i < fields.length; i++) {
            Field f = fields[i];

            //获取属性的名称
            String key = f.getName();

            //跳过属性的权限检查
            f.setAccessible(true);

            //都是字符串 操作  进行判断
            //如果属性的类型是int 判断int.class   如果是Ingeter 判断为 Integer.class
            if (f.getType() == int.class){
                f.set(t,Integer.valueOf(map.get(key)));
            }else if (f.getType() == String.class){
                f.set(t,Double.valueOf(map.get(key)));
            }else{
                f.set(t,map.get(key));
            }

        }
        return clazz;
    }

    public static Map<String,Object> convertBean2Map(Object obj) {
        return Arrays.stream(BeanUtils.getPropertyDescriptors(obj.getClass()))
                .filter(itm -> !"class".equals(itm.getName()))
                .collect(HashMap::new,
                        (map, pd) -> map.put(String.valueOf(pd.getName()), ReflectionUtils.invokeMethod(pd.getReadMethod(), obj)),
                        HashMap::putAll);
    }
}
